package com.marco.statics.websocket;

import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;

/**
 * WebSocketHander.java
 * Create on 2017/4/10
 * Copyright(c) JD Inc 2017. All Rights Reserved.
 * <pre>
 * 功能说明：webSocket处理类
 * </pre>
 */
@Component
public class WebSocketHander extends TextWebSocketHandler {
    private static final Logger logger = LoggerFactory.getLogger(WebSocketHander.class);
    //当前用户HASH表
    private static Map<String, WebSocketSession> currentUsers;

    static {
        currentUsers = Maps.newHashMap();
    }

    /**
     * 成功建立链接之后记录当前用户
     *
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String userId = getUserId(session);
//        logger.info("用户 {} 成功建立链接", userId);
        if (StringUtils.isNotBlank(userId)) {
            currentUsers.put(userId, session);
            session.sendMessage(new TextMessage("成功建立链接"));
        }
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        logger.info("客户端上传信息为 {}", message.getPayload());
        try {
            String type = message.getPayload();
            if (type.equals("REAL_TIME")) {
                while (session.isOpen()) {
                    session.sendMessage(new TextMessage("server:" + message));
                    Thread.sleep(10000);
                }
            }
        } catch (Exception e) {
            logger.error("处理客户端上传信息出现异常", e);
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if (session.isOpen()) {
            session.close();
        }
        String userId = getUserId(session);
//        logger.error("当前用户 {} 链接出现异常 ", userId);
        currentUsers.remove(userId);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String userId = getUserId(session);
//        logger.info("用户 {} 已经退出", userId);
        currentUsers.remove(userId);
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 发送信息给指定用户
     *
     * @param userId  用户的Id
     * @param message 发送的消息
     * @return
     */
    public boolean sendMessageToUser(String userId, TextMessage message) {
        if (currentUsers.get(userId) == null) {
            return false;
        }
        WebSocketSession session = currentUsers.get(userId);
        if (!session.isOpen()) {
            return false;
        }
        try {
            session.sendMessage(message);
        } catch (IOException e) {
            logger.error("给指定用户 {} 发送消息出现异常", e);
            return false;
        }
        return true;
    }

    /**
     * 广播信息
     *
     * @param message
     * @return
     */
    public boolean sendMessageToAllUsers(TextMessage message) {
        Collection<WebSocketSession> sets = currentUsers.values();
        for (WebSocketSession session : sets) {
            if (session.isOpen()) {
                try {
                    session.sendMessage(message);
                } catch (IOException e) {
                    logger.error("指定用户 {} 发送广播消息出现异常", getUserId(session));
                }
            }
        }
        return true;
    }


    /**
     * 根据session获取用户ID
     *
     * @param session
     * @return
     */
    private String getUserId(WebSocketSession session) {
        try {
            String userId = session.getId();
        } catch (Exception e) {
            return null;
        }
        return null;
    }
}
